<template>
  <div>
    <!-- 按钮和搜索框 -->
    <el-input
      type="text"
      v-model="input"
      placeholder="请输入查询交通事故信息"
      class="myinput"
      :prefix-icon="Search"
    >
    </el-input>

    <!-- 1、创建popup DOM -->
    <div id="popup" class="ol-popup">
      <header class="pop_header">
        事件详细信息
        <a href="#" id="popup-closer-es" class="ol-popup-closer"></a>
      </header>
      <div id="popup-content">
        <table v-if="event_value">
          <tr
            v-show="keyIsShow(key)"
            v-for="(value, key) in event_value"
            :key="key"
          >
            <td class="event_key">{{ key }}</td>
            <td>{{ valueToFormat(key, value) }}</td>
          </tr>
        </table>
      </div>
    </div>
  </div>
</template>

<script setup>
import { Search } from "@element-plus/icons-vue";
import { computed } from "vue";
import { app } from "../../main";
import { Query } from "../../utils/Query";
import { usePiniaStore } from "../../stores/pinia";
import { storeToRefs } from "pinia";
// 设置事件点的三种颜色
import { TraEventManageHooks } from "../../views/home/components/traffic/TrafficEventManage/TraEventManageHooks";
const { trafficEventStyle } = TraEventManageHooks();

const piniaStore = usePiniaStore();
// 用户信息
const { userInfo } = storeToRefs(piniaStore);
const input = ref("");
// 每次点击事件要素时得到的事件信息对象
const event_value = ref(null);
let $map = null;
// popup图层
let popup = null;
// 高亮图层的数据源
let source = new ol.source.Vector({
  wrapX: false,
});
// 注入全局挂载的 上方导航栏的事件查询拉框画笔图层的数据源【来自src/components/EventSearch/EventSearch组件】// 响应式数据
const $sourceDraw = inject("$sourceDraw");

// 全局挂载 evtSource // 事件高亮图层的数据源
app.provide("$evtSource", source);

// 通过Style类创建icon 【图片标注的样式】
const icon = new ol.style.Style({
  /**{olx.style.IconOptions}类型*/
  image: new ol.style.Icon({
    // 0.5 1 // x轴在中心 // y轴在底部
    anchor: [0.5, 40],
    anchorOrigin: "top-right",
    anchorXUnits: "fraction",
    anchorYUnits: "pixels",
    offsetOrigin: "top-right",
    // offset:[0,10],
    //图标缩放比例
    scale: 0.6,
    //透明度
    opacity: 0.75,
    //图标的url
    src: "/src/components/EventSearch/images/location.png",
    // src: 'https://openlayers.org/en/v6.5.0/examples/data/icon.png' // OpenLayers 内置的标注图标
  }),
});
let highLightLayer = new ol.layer.Vector({
  source,
  zIndex: 2,
  style: icon,
});
onMounted(() => {
  $map = inject("$map");
  // 添加高亮图层
  $map.addLayer(highLightLayer);
  // 创建一个带有关闭功能的popup弹框
  createPopup();
  // 添加popup图层到地图中
  $map.addOverlay(popup);
  // 鼠标移动到地图要素上,显示抓手
  showPointer();
  // 点击要素,获取要素点的位置,将popup显示到对应位置
  showPopup();
});

// 函数：根据关键词查询某个图层上的相关要素，并将其展示在地图的高亮图层
const searchKeyWordEventFeature = () => {
  //未定义popup位置【清除上次搜素产生的popup】
  popup.setPosition(undefined);
  // console.log(1);
  source.clear();
  // 定义想要查询的字段【普通用户和管理人员不同】
  const fields =
    userInfo.value.type === "common"
      ? ["事件类型", "事件等级", "发生时间", "发生地点", "处理状态"]
      : [
          "事件编号",
          "事件类型",
          "事件等级",
          "发生时间",
          "发生地点",
          "车牌号",
          "驾驶员",
          "处理状态",
        ];
  // 定义想要查询的服务和图层
  const service = {
    name: "guanggu",
    layerId: 2,
  };
  // 定义查询成功的回调函数
  const success = function querySuccess(data) {
    // 对查到的data数据进行解密，MapGIS要素JSON反序列化为ol.Feature类型数组
    let format = new Zondy.Format.PolygonJSON();
    let features = format.read(data);
    // console.log(features);// 查不到的时候是null // 查到的时候就是[e,e,e]，所查到要素的数组
    if (features) {
      // 如果能插到数据，就1. 根据要素字段不同的处理状态给feature设置不同的样式
      // 2.将新查到的要素添加到数据源中
      features.forEach((item) => {
        let styleTrafEvt = trafficEventStyle(item.values_.values_.处理状态);
        item.setStyle(styleTrafEvt);
        // console.log( item.values_.values_.处理状态);
      });
      source.addFeatures(features);
    }
  };
  // 查询
  // queryByAttr({ keyword, fields, service, success })
  Query.queryByAttr({ keyword: input.value, fields, service, success });
};
// 函数：当input输入框的值变化且不为空时，调用这个函数
const inputValueChangeSearch = () => {
  // 1. 清空之前的数据源
  source.clear();
  // 2. 查询后台要素，将其展示在地图的高亮图层
  searchKeyWordEventFeature();
};
// 创建一个带有关闭功能的popup弹框
const createPopup = () => {
  // 获取DOM：实现popup的html元素
  let container = document.getElementById("popup");
  let closer = document.getElementById("popup-closer-es");
  // 在地图容器中创建一个Overlay
  popup = new ol.Overlay(
    /** @type {olx.OverlayOptions} */
    ({
      //要转换成overlay的HTML元素
      element: container,
      //当前窗口可见
      autoPan: true,
      //Popup放置的位置
      positioning: "bottom-center",
      //是否应该停止事件传播到地图窗口
      stopEvent: true,
      // stopEvent: false,
      autoPanAnimation: {
        //当Popup超出地图边界时，为了Popup全部可见，地图移动的速度
        duration: 250,
      },
    })
  );
  // 关闭popup弹窗
  closer.onclick = function () {
    //未定义popup位置
    popup.setPosition(undefined);
    //失去焦点
    closer.blur();
    return false;
  };
};
// 函数：鼠标移动到地图要素上,显示抓手
const showPointer = () => {
  $map.on("pointermove", function (e) {
    let pixel = $map.getEventPixel(e.originalEvent);
    let hit = $map.hasFeatureAtPixel(pixel);
    $map.getTargetElement().style.cursor = hit ? "pointer" : "";
  });
};
// 函数：点击要素,获取要素点的位置,将popup显示到对应位置
const showPopup = () => {
  $map.on("click", function (evt) {
    //判断当前单击处是否有要素，捕获到要素时弹出popup
    let feature = $map.forEachFeatureAtPixel(
      evt.pixel,
      function (feature, layer) {
        return feature;
      }
    );
    // 没有feature就直接退出
    if (!feature) return;
    // console.log(feature);
    // 判断点击的要素是否处在我的事件高亮图层上（是不是事件高亮图层的要素）
    if (!highLightLayer.getSource().getFeatures().includes(feature)) {
      // console.log(2);
      // 如果不在，就return
      return;
    }
    // if (feature){
    // 如果只写feature，那拉框时，拉的框也是一个feature，也会进入以下代码块
    // 引起报错。所以还要判断feature.values_.values_是否存在
    if (feature.values_.values_) {
      //每次点击其他的要素前，先关闭之前的弹框，// 即修改为未定义popup位置
      popup.setPosition(undefined);
      // console.log(feature.values_.values_);
      let new_value = {};
      Object.keys(feature.values_.values_).forEach((item) => {
        if (item !== "mpLayer") {
          new_value[item] = feature.values_.values_[item];
        }
      });
      event_value.value = new_value;
      // console.log(event_value.value);
      // console.log(feature.get("center"));
      if (popup.getPosition() == undefined) {
        // content.innerHTML =

        //设置popup的位置
        let position = feature.getGeometry().getCoordinates()[0];
        // console.log(feature.getGeometry())
        // console.log(position);
        popup.setPosition(position);
      }
    }
  });
};
// 根据用户类型判断是否展示popup弹窗的key
const keyIsShow = computed(() => {
  return (key) => {
    if (userInfo.value.type === "common") {
      // 普通用户看不到这几个属性
      return !(key === "车牌号" || key === "驾驶员" || key === "事件编号");
    } else {
      return true;
    }
  };
});
// 格式化popup弹窗的value 为已处理
const valueToFormat = (key, value) => {
  if (key === "处理状态") {
    switch (value) {
      case "0":
        return "待处理";
        break;
      case "1":
        return "处理中";
        break;
      case "2":
        return "已归档";
      default:
        return "处理状态未知";
    }
  } else if (key === "事件等级") {
    switch (value) {
      case "1":
        return "轻微事故";
        break;
      case "2":
        return "一般事故";
        break;
      case "3":
        return "重大事故";
        break;
      case "4":
        return "特大事故";
        break;
      default:
        return "事件类型未知";
    }
  } else {
    return value;
  }
};
// watch监听输入框内容的变化，只要有变化就重新查询后台地图数据，将之前的数据源清空，弹框清除，新查询的要素添加到数据源
// 输入框内容清空的时候，不去查询后台数据，并且要清空当前已有的数据源。
watch(input, (newval) => {
  if (newval === "") {
    // 不查询后台数据且清空当前的数据源
    source.clear();
    // 且把弹框设置为未定义位置（清除弹框）
    popup.setPosition(undefined);
  } else {
    // 查询后台数据，获取查询到的最新要素，清空之前的数据源，将最新的要素添加到数据
    inputValueChangeSearch();
  }
});
</script>

<style lang="scss" scoped>
.el-input.el-input--prefix.myinput {
  align-self: center;
  height: 40px;
  width: 270px;
  :deep(.el-input__wrapper) {
    .el-input__inner {
      padding-left: 10px;
    }
  }
}

table {
  border-collapse: collapse;
  td,
  th {
    border: 1px solid #000;
    padding: 5px;
    &.event_key {
      width: 80px;
      font-weight: 700;
      writing-mode: horizontal-tb;
      padding-left: 10px;
    }
  }
}

.ol-popup {
  position: absolute;
  z-index: 1000;
  width: 260px;
  height: 200px;
  background-color: white;
  -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 30px;
  left: -60px;
  &::after {
    content: "";
    position: absolute;
    bottom: -10px;
    left: 50px;
    width: 0;
    height: 0;
    border-left: 13px solid transparent;
    border-right: 13px solid transparent;
    border-top: 15px solid #fff;
  }
  // &::after {
  //   border-top-color: white;
  //   border-width: 10px;
  //   left: 48px;
  //   margin-left: -10px;
  // }

  // &::before {
  //   border-top-color: #cccccc;
  //   border-width: 11px;
  //   left: 48px;
  //   margin-left: -11px;
  // }
  .pop_header {
    border-radius: 10px 10px 0 0;
    // background-color: #2196f3;
    height: 30px;
    line-height: 30px;
    padding-left: 11px;
    font-weight: 700;
  }
  .ol-popup-closer {
    text-decoration: none;
    position: absolute;
    top: 2px;
    right: 8px;
    &:after {
      content: "✖";
      color: #000;
    }
  }
  #popup-content {
    height: 160px;
    padding-inline: 15px;
    padding-top: 10px;
    font-size: 14px;
    font-family: "微软雅黑";
    overflow-y: auto;
    &.markerInfo {
      font-weight: bold;
    }
  }
}
</style>
